# -*- coding: utf-8 -*-

import os
import tkinter as tk
from tkinter import filedialog, colorchooser, ttk, messagebox
from PyPDF2 import PdfReader, PdfWriter
from reportlab.pdfgen import canvas
import io
import threading


class PDFEyeProtectionApp:
    def __init__(self, root):
        self.root = root
        self.root.title("PDF护眼背景色添加工具")

        # 设置窗口尺寸但不设置位置
        self.root.geometry("600x450")

        # 只禁止调整大小，保留最小化按钮
        self.root.resizable(False, False)  # 禁止调整窗口大小

        # 创建强调按钮样式
        style = ttk.Style()
        style.configure("Accent.TButton", font=("微软雅黑", 10, "bold"))
        # pyinstaller -F -i -w xxx.ico xxx.py
        # 设置默认护眼色 (232, 246, 232) - 淡绿色
        self.bg_color = (232, 246, 232)

        # 置顶状态标志
        self.is_topmost = False

        # 设置窗口居中 - 在创建界面之前设置
        self.center_window()

        # 创建界面
        self.create_widgets()

        # 设置窗口图标
        try:
            self.root.iconbitmap("icon.ico")
        except:
            pass

    def center_window(self):
        # 获取屏幕宽度和高度
        screen_width = self.root.winfo_screenwidth()
        screen_height = self.root.winfo_screenheight()

        # 获取窗口宽度和高度
        window_width = 600
        window_height = 450

        # 计算居中位置坐标
        x = (screen_width - window_width) // 2
        y = (screen_height - window_height) // 2

        # 设置窗口位置
        self.root.geometry(f"{window_width}x{window_height}+{x}+{y}")

    def toggle_topmost(self):
        # 切换置顶状态
        self.is_topmost = not self.is_topmost
        self.root.attributes("-topmost", self.is_topmost)

        # 更新按钮文本
        if self.is_topmost:
            self.topmost_btn.config(text="取消置顶")
        else:
            self.topmost_btn.config(text="窗口置顶")

    def create_widgets(self):
        # 创建主框架
        main_frame = ttk.Frame(self.root, padding="20 20 20 20")
        main_frame.pack(fill=tk.BOTH, expand=True)

        # 文件选择区域
        file_frame = ttk.LabelFrame(main_frame, text="文件选择", padding="10 10 10 10")
        file_frame.pack(fill=tk.X, pady=10)

        ttk.Label(file_frame, text="输入PDF文件:").grid(
            row=0, column=0, sticky=tk.W, pady=5
        )

        self.input_file_var = tk.StringVar()
        input_entry = ttk.Entry(file_frame, textvariable=self.input_file_var, width=50)
        input_entry.grid(row=0, column=1, padx=5, pady=5, sticky=tk.W + tk.E)

        browse_btn = ttk.Button(
            file_frame, text="浏览...", command=self.browse_input_file
        )
        browse_btn.grid(row=0, column=2, padx=5, pady=5)

        # 输出文件路径显示
        ttk.Label(file_frame, text="输出PDF文件:").grid(
            row=1, column=0, sticky=tk.W, pady=5
        )

        self.output_file_var = tk.StringVar()
        output_entry = ttk.Entry(
            file_frame, textvariable=self.output_file_var, width=50
        )
        output_entry.grid(row=1, column=1, padx=5, pady=5, sticky=tk.W + tk.E)

        save_as_btn = ttk.Button(
            file_frame, text="另存为...", command=self.browse_output_file
        )
        save_as_btn.grid(row=1, column=2, padx=5, pady=5)

        # 颜色选择区域
        color_frame = ttk.LabelFrame(
            main_frame, text="背景色选择", padding="10 10 10 10"
        )
        color_frame.pack(fill=tk.X, pady=10)

        # 默认护眼色选项
        default_colors_frame = ttk.Frame(color_frame)
        default_colors_frame.pack(fill=tk.X, pady=5)

        ttk.Label(default_colors_frame, text="预设护眼色:").grid(
            row=0, column=0, sticky=tk.W, padx=5
        )

        # 创建几种常用护眼色按钮
        colors_frame = ttk.Frame(default_colors_frame)
        colors_frame.grid(row=0, column=1, sticky=tk.W)

        # 几种常用护眼色
        eye_colors = [
            ("淡绿色", (232, 246, 232)),
            ("米黄色", (250, 249, 222)),
            ("淡蓝色", (233, 245, 254)),
            ("淡粉色", (253, 242, 248)),
        ]

        for i, (color_name, rgb) in enumerate(eye_colors):
            color_btn = ttk.Button(
                colors_frame, text=color_name, command=lambda c=rgb: self.set_color(c)
            )
            color_btn.grid(row=0, column=i, padx=5, pady=5)

        # 自定义颜色
        custom_color_frame = ttk.Frame(color_frame)
        custom_color_frame.pack(fill=tk.X, pady=5)

        ttk.Label(custom_color_frame, text="自定义颜色:").grid(
            row=0, column=0, sticky=tk.W, padx=5
        )

        self.color_preview = tk.Canvas(
            custom_color_frame, width=30, height=20, bg=self.rgb_to_hex(self.bg_color)
        )
        self.color_preview.grid(row=0, column=1, padx=5)

        choose_color_btn = ttk.Button(
            custom_color_frame, text="选择颜色", command=self.choose_custom_color
        )
        choose_color_btn.grid(row=0, column=2, padx=5)

        # RGB值显示
        rgb_frame = ttk.Frame(color_frame)
        rgb_frame.pack(fill=tk.X, pady=5)

        ttk.Label(rgb_frame, text="RGB值:").grid(row=0, column=0, sticky=tk.W, padx=5)

        self.rgb_var = tk.StringVar(
            value=f"R: {self.bg_color[0]}, G: {self.bg_color[1]}, B: {self.bg_color[2]}"
        )
        ttk.Label(rgb_frame, textvariable=self.rgb_var).grid(
            row=0, column=1, sticky=tk.W, padx=5
        )

        # 进度条
        progress_frame = ttk.Frame(main_frame)
        progress_frame.pack(fill=tk.X, pady=10)

        self.progress_var = tk.DoubleVar()
        self.progress_bar = ttk.Progressbar(
            progress_frame, variable=self.progress_var, maximum=100
        )
        self.progress_bar.pack(fill=tk.X, pady=5)

        # 状态显示和置顶按钮并排
        status_frame = ttk.Frame(progress_frame)
        status_frame.pack(fill=tk.X, pady=5)

        self.status_var = tk.StringVar(value="准备就绪")
        status_label = ttk.Label(
            status_frame, textvariable=self.status_var, anchor=tk.W
        )
        status_label.pack(side=tk.LEFT, fill=tk.X, expand=True)

        # 在状态行添加明显的开始处理按钮
        process_btn = ttk.Button(
            status_frame,
            text="开始处理",
            command=self.start_processing,
            # style="Accent.TButton",  # 文字加粗
            width=10,
        )
        process_btn.pack(side=tk.RIGHT, padx=5)

        # 将置顶按钮放在状态标签旁边
        self.topmost_btn = ttk.Button(
            status_frame, text="窗口置顶", command=self.toggle_topmost
        )
        self.topmost_btn.pack(side=tk.RIGHT, padx=5)

        # 操作按钮
        button_frame = ttk.Frame(main_frame)
        button_frame.pack(fill=tk.X, pady=20)

        exit_btn = ttk.Button(button_frame, text="退出", command=self.root.destroy)
        exit_btn.pack(side=tk.RIGHT, padx=5)

    def browse_input_file(self):
        filename = filedialog.askopenfilename(
            title="选择PDF文件", filetypes=[("PDF文件", "*.pdf"), ("所有文件", "*.*")]
        )
        if filename:
            self.input_file_var.set(filename)
            # 自动生成输出文件名
            file_name, file_ext = os.path.splitext(filename)
            self.output_file_var.set(f"{file_name}_护眼版{file_ext}")

    def browse_output_file(self):
        filename = filedialog.asksaveasfilename(
            title="保存PDF文件",
            filetypes=[("PDF文件", "*.pdf"), ("所有文件", "*.*")],
            defaultextension=".pdf",
        )
        if filename:
            self.output_file_var.set(filename)

    def set_color(self, rgb):
        self.bg_color = rgb
        hex_color = self.rgb_to_hex(rgb)
        self.color_preview.config(bg=hex_color)
        self.rgb_var.set(f"R: {rgb[0]}, G: {rgb[1]}, B: {rgb[2]}")

    def choose_custom_color(self):
        color = colorchooser.askcolor(
            title="选择背景色", initialcolor=self.rgb_to_hex(self.bg_color)
        )
        if color[0]:  # color is ((r, g, b), hex_string)
            r, g, b = [int(c) for c in color[0]]
            self.set_color((r, g, b))

    def rgb_to_hex(self, rgb):
        return f"#{rgb[0]:02x}{rgb[1]:02x}{rgb[2]:02x}"

    def start_processing(self):
        input_file = self.input_file_var.get().strip()
        output_file = self.output_file_var.get().strip()

        if not input_file:
            messagebox.showerror("错误", "请选择输入PDF文件")
            return

        if not output_file:
            messagebox.showerror("错误", "请指定输出PDF文件")
            return

        if not os.path.exists(input_file):
            messagebox.showerror("错误", f"文件不存在: {input_file}")
            return

        # 使用线程处理PDF，避免界面卡死
        self.progress_var.set(0)
        self.status_var.set("正在处理...")

        processing_thread = threading.Thread(
            target=self.process_pdf, args=(input_file, output_file, self.bg_color)
        )
        processing_thread.daemon = True
        processing_thread.start()

    def process_pdf(self, input_pdf_path, output_pdf_path, bg_color):
        try:
            # 读取原始PDF
            reader = PdfReader(input_pdf_path)
            writer = PdfWriter()
            total_pages = len(reader.pages)

            # 处理每一页
            for page_num in range(total_pages):
                # 更新进度
                progress = (page_num + 1) / total_pages * 100
                self.root.after(0, lambda p=progress: self.progress_var.set(p))
                self.root.after(
                    0,
                    lambda n=page_num + 1, t=total_pages: self.status_var.set(
                        f"正在处理第 {n}/{t} 页..."
                    ),
                )

                # 获取原始页面
                page = reader.pages[page_num]
                page_width = float(page.mediabox.width)
                page_height = float(page.mediabox.height)

                # 创建一个带有背景色的新页面
                packet = io.BytesIO()
                c = canvas.Canvas(packet, pagesize=(page_width, page_height))

                # 设置背景色
                r, g, b = bg_color
                c.setFillColorRGB(r / 255, g / 255, b / 255)
                c.rect(0, 0, page_width, page_height, fill=True, stroke=False)
                c.save()

                # 将背景添加到页面下方
                packet.seek(0)
                background_pdf = PdfReader(packet)
                background_page = background_pdf.pages[0]

                # 合并背景和原始页面
                background_page.merge_page(page)
                writer.add_page(background_page)

            # 保存新PDF
            with open(output_pdf_path, "wb") as output_file:
                writer.write(output_file)

            # 更新状态
            self.root.after(0, lambda: self.progress_var.set(100))
            self.root.after(0, lambda: self.status_var.set("处理完成！"))
            self.root.after(
                0,
                lambda: messagebox.showinfo(
                    "完成", f"PDF处理完成！\n文件已保存为: {output_pdf_path}"
                ),
            )

        except Exception as e:
            self.root.after(0, lambda: self.status_var.set(f"处理失败: {str(e)}"))
            self.root.after(
                0, lambda: messagebox.showerror("错误", f"处理PDF时出错:\n{str(e)}")
            )


def main():
    root = tk.Tk()
    app = PDFEyeProtectionApp(root)
    root.mainloop()


if __name__ == "__main__":
    main()
